#pragma once

/** @file
 *
 * This file is a adaptor of FUSE
 *
 * IMPORTANT: you should init adaptor by your filesystem before using it.
 */

#define FUSE_USE_VERSION 31
#include <fuse.h>
#include <myFs/simpleFS.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstddef>
#include <shared_mutex>
namespace adaptor {
namespace fuse {

/// 这是一个单例(好像没有必要orz)
class Adaptor {
  public:
    using FS = typename myFs::basic::SimpleFS;

  private:
    Adaptor(FS *pFS);

  public:
    static Adaptor &init(FS &FS);
    static FS &     myFS();

  private:
    static inline FS *              m_pFS;
    static inline std::shared_mutex s_mtx = std::shared_mutex{};

  public:
    static int getattr(const char *path, struct stat *st, struct fuse_file_info *fi);
    static int mknod(const char *path, mode_t mode, dev_t);
    static int mkdir(const char *path, mode_t mode);
    static int rmdir(const char *path);
    static int rename(const char *path1, const char *path2, unsigned int flags);
    static int read(const char *path, char *buf, std::size_t size, off_t off, struct fuse_file_info *);
    static int write(const char *path, const char *data, std::size_t size, off_t off, struct fuse_file_info *);
    static int statfs(const char *, struct statvfs *);
    static int readdir(
        const char *path, void *buf, fuse_fill_dir_t filler, off_t, struct fuse_file_info *, enum fuse_readdir_flags);
    static int open(const char *path, struct fuse_file_info *fi);
    static int unlink(const char *path);
    static int releasedir(const char *path, struct fuse_file_info *fi);
};

}  // namespace fuse

}  // namespace adaptor